/**
 * 右侧的tree
 */

import React from 'react';
import { Balloon, Button } from '@teamix/ui';
import MarkdownIt from 'markdown-it';
import MarkdownItReplaceLink from 'markdown-it-replace-link';
import hljs from 'utils/hl.js';
import { navigate, getPathWithRootPath, HrefLink } from 'utils/router';
import utils from 'utils';
import track from 'utils/track';
import FilePanel from 'components/filePanel';
import { PROJECT_WRITE_ROLES } from 'utils/constants.js';
import { access, protectBranchCheck } from 'components/accessContainer/util';
import { ENUM } from 'utils/constants';
import { filterXSS } from 'xss';
import FileIcon from 'components/fileIcon';
import LfsTag from 'components/lfs/lfsTag';
import ListEmpty from 'atComponents/ListEmpty';
import { Perf } from '@alife/yunxiao-common';
import PanelSkeleton from './components/skeleton';
import intl from '../../../../../../../../locale';

const { Tooltip } = Balloon;

const { pathResource, resourceSubject } = window.FORCE;
const md = new MarkdownIt({
  html: true,
  // linkify: true,
  highlight(str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return `<pre><code class="hljs">${hljs.highlightAuto(str).value}</code></pre>`;
      } catch (_) {
        return '';
      }
    }
    return '';
  },
  replaceLink(link, env, token) {
    // 若 md 中链接不以 http 开头且非以 # 开头（这种是锚点），普通链接在前面加上 blobPathPrefix，图片链接加上 rawPathPrefix
    // 此逻辑与gitlab保持一致
    const blobPathPrefix = getPathWithRootPath(`/${pathResource.fullPath}/blob/${utils.revisionEncodeURI(
      resourceSubject.revision,
    )}/`);
    const rawPathPrefix = getPathWithRootPath(`/${pathResource.fullPath}/raw/${utils.revisionEncodeURI(
      resourceSubject.revision,
    )}/`);
    if (link.indexOf('http') !== 0 && link.indexOf('#') !== 0) {
      if (token.type === 'image') {
        return `${rawPathPrefix}${link}`;
      } else {
        return `${blobPathPrefix}${link}`;
      }
    }
    // 链接新开窗口
    token.attrPush(['target', '_blank']);
    return link;
  },
}).use(MarkdownItReplaceLink);

export default class TreeRight extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      hasFetchBlob: false,
    };
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    this.fetchReadmeBlob(nextProps);
  }

  fetchReadmeBlob = (props) => {
    const { currentTreeData, get_general_info_and_blobs, resourcePath } = props;

    if (this.state.hasFetchBlob) {
      return false;
    }

    if (currentTreeData.length) {
      const readmeName = this.getReadmeName(currentTreeData);
      const readmePath = `${resourcePath}${resourcePath && '/'}${readmeName}`;

      if (!readmePath) {
        return false;
      }

      get_general_info_and_blobs(readmePath);

      this.setState({
        hasFetchBlob: true,
      });
    }
  };

  getReadmeName = (currentTreeData) => {
    if (!currentTreeData.length) {
      return '';
    }
    let readmeName;
    // 优先readme.md --- readme  --- 含有readme
    const readme_md_file = currentTreeData.find((file) => {
      return file.type === 'blob' && file.name.toLowerCase() === 'readme.md';
    });
    const readmd_file = currentTreeData.find((file) => {
      return file.type === 'blob' && file.name.toLowerCase() === 'readme';
    });
    const contain_readme_file = currentTreeData.find((file) => {
      return file.type === 'blob' && file.name.toLowerCase().indexOf('readme') !== -1;
    });
    const cur_readme_file = readme_md_file || readmd_file || contain_readme_file;
    if (cur_readme_file) {
      readmeName = cur_readme_file.name;
    }
    return readmeName || '';
  };

  onTreeItemSelect = (info, e) => {
    const blobPathPrefix = `/${pathResource.fullPath}/blob/${utils.revisionEncodeURI(
      resourceSubject.revision,
    )}/`;
    const { isLeaf } = e.node.props;

    if (isLeaf) {
      navigate(blobPathPrefix + info[0], { state: { forceUpdate: true } });
    }
  };

  goAddReadme = () => {
    const defaultBranch = window.FORCE.pathResource.defaultBranch || 'master';
    navigate(`/${pathResource.fullPath}/new/${defaultBranch}?file_name=README.md`);

    this.props.updateSetSelectedType({
      resourceSubject: {
        subject: 'new',
        path: '',
      },
    });
  };

  renderBlob = (readmeBlob, readmePath) => {
    const { is_lfs, fileReqFailInfo } = this.props;

    // 请求异常时，显示错误原因
    if (fileReqFailInfo) {
      return (
        <ListEmpty
          size="small"
          type="card"
          content={fileReqFailInfo}
          image="none"
          className="no-content no-btns"
        />
      );
    }
    if (is_lfs) {
      return (
        <div style={{ textAlign: 'center' }}>
          <HrefLink
            className="text-black"
            style={{ fontSize: '16px', display: 'block', margin: '12px 0 12px' }}
            href={`/${pathResource.fullPath}/raw/${utils.revisionEncodeURI(
              resourceSubject.revision,
            )}/${readmePath}`}
            target="_blank"
            rel="noreferrer"
          >
            {intl.get({
              id: 'code-assets.src.utils.locale.ClickToViewTheOriginal',
              defaultMessage: '点击查看原始文件',
            })}
          </HrefLink>
        </div>
      );
    }
    return (
      <div
        className="markdown-body"
        dangerouslySetInnerHTML={{
          __html: filterXSS(md.render(readmeBlob || '')),
        }}
      />
    );
  };

  getErrorHintMessage = (data) => {
    if (data.isMirrorSynchronizing) {
      return intl.get({
        id: 'code-assets.containers.content.treeRight.TheRepositoryIsBeingSynchronized',
        defaultMessage: '仓库同步中，暂不支持操作，请稍后再试',
      });
    }

    if (data.isDeveloper) {
      return intl.get({
        id: 'code-assets.containers.content.treeRight.TheCurrentBranchIsProtected',
        defaultMessage: '当前为保护分支，无权限直接推送，请联系管理员处理',
      });
    }

    return intl.get({
      id: 'code-assets.containers.content.treeRight.CurrentlyItIsAProtected',
      defaultMessage: '当前为保护分支，无权限直接推送，可前往设置处理',
    });
  };

  readmePreviewJsx = () => {
    const {
      currentTreeData,
      resourcePath,
      blob,
      filesViewType,
      protectedBranch,
      is_lfs,
      lastMirrorSyncRecord,
    } = this.props;
    const { role } = pathResource;
    const isHomePage = resourcePath === ''; // 是代码库概览

    const { access_level } = ENUM;
    const allowProtectPush = protectBranchCheck(protectedBranch, role);
    const isDeveloper = role === access_level[30];

    const readmeName = this.getReadmeName(currentTreeData);
    const readmePath = `${resourcePath}${resourcePath && '/'}${readmeName}`;

    // 如果根路径没有readme，则提示添加readme

    const isArchive = window.FORCE.pathResource && window.FORCE.pathResource.isArchive === 'true';
    let isMirrorSynchronizing = false;
    if (lastMirrorSyncRecord) {
      isMirrorSynchronizing = utils.isMirrorSynchronizing(lastMirrorSyncRecord.sync_status);
    }

    if (!readmePath && isHomePage) {
      if (
        access(PROJECT_WRITE_ROLES, role) &&
        allowProtectPush &&
        !isArchive &&
        !isMirrorSynchronizing
      ) {
        return (
          <ListEmpty
            style={{ marginTop: '116px' }}
            content=""
            desc={intl.get({
              id: 'code-assets.containers.content.treeRight.TheCurrentRepositoryDoesNot',
              defaultMessage: '当前仓库没有 README 文件',
            })}
            image="https://img.alicdn.com/tfs/TB1xfUyhXY7gK0jSZKzXXaikpXa-400-320.png"
            extra={
              <Button
                type="primary"
                onClick={() => {
                  track({
                    action: 'new_readme',
                    page: 'Repo-Files',
                  });

                  this.goAddReadme();
                }}
              >
                {intl.get({
                  id: 'code-assets.containers.content.treeRight.AddNow',
                  defaultMessage: '立即添加',
                })}
              </Button>
            }
          />
        );
      } else if (!access(PROJECT_WRITE_ROLES, role) || isArchive) {
        return (
          <ListEmpty
            style={{ marginTop: '116px' }}
            content=""
            desc={intl.get({
              id: 'code-assets.containers.content.treeRight.TheCurrentRepositoryDoesNot',
              defaultMessage: '当前仓库没有 README 文件',
            })}
            image="https://img.alicdn.com/tfs/TB1xfUyhXY7gK0jSZKzXXaikpXa-400-320.png"
          />
        );
      } else {
        return (
          <ListEmpty
            style={{ marginTop: '116px' }}
            content=""
            desc={intl.get({
              id: 'code-assets.containers.content.treeRight.TheCurrentRepositoryDoesNot',
              defaultMessage: '当前仓库没有 README 文件',
            })}
            image="https://img.alicdn.com/tfs/TB1xfUyhXY7gK0jSZKzXXaikpXa-400-320.png"
            extra={
              <Tooltip
                trigger={
                  <Button type="primary" disabled>
                    {intl.get({
                      id: 'code-assets.containers.content.treeRight.AddNow',
                      defaultMessage: '立即添加',
                    })}
                  </Button>
                }
                align="t"
                text={this.getErrorHintMessage({
                  isDeveloper,
                  isMirrorSynchronizing,
                })}
              />
            }
          />
        );
      }
    }

    if (!readmePath || blob === null || blob.encoding === 'base64') {
      return null;
    }

    // 如果有对应的喜码任务，且为首页的readme，且未接入喜码徽章，则渲染喜码徽章
    const readmeBlob = blob;

    return (
      <FilePanel
        style={{ marginTop: `${!(isHomePage && filesViewType === 'tree') ? '20px' : ''}` }}
      >
        <FilePanel.Header className="file-box-header">
          <div>
            <FileIcon className="header-file-icon" fileName={readmeName} />
            <span className="display-inline-block">{readmeName}</span>
            {is_lfs && <LfsTag role={role} />}
          </div>
        </FilePanel.Header>
        <FilePanel.Body>{this.renderBlob(readmeBlob, readmePath)}</FilePanel.Body>
      </FilePanel>
    );
  };

  render() {
    const { isInitedLeftTree, isGettingBlob } = this.props;
    // 树结构还没初始化玩成，return false
    if (!isInitedLeftTree) {
      return false;
    }
    if (isGettingBlob) {
      return <PanelSkeleton delay={1000} />;
    }

    // 只有概览做readme选中展示或提醒添加的逻辑，其他目录不做。readme展示的区域如果是树视图展示在右侧内容区，普通视图展示在列表下面
    // 首页，只显示readme
    return (
      <div>
        {this.readmePreviewJsx()}
        <Perf />
      </div>
    );
  }
}
